

		/* ASSIGN, Assignment Problem */
		/* The assignment problem is one of the fundamental combinatorial optimization problems.
		In its most general form, the problem is as follows:
		There are a number of agents and a number of tasks. Any agent can be assigned to perform any task, incurring some cost that may vary depending on the agent-task assignment. It is required to perform all tasks by assigning exactly one agent to each task in such a way that the total cost of the assignment is minimized.
		(From Wikipedia, the free encyclopedia.) */

set PERSON:= {1,2,3,4,5,6,7,8,9,10,11};
		/* set of agents */
set TASK:= {1,2,3,4,5,6,7,8,9,10};
		/* set of tasks */
set SKILL:= {1,2,3,4,5,6};
		/* set of skill */
set PERIOD:= {1,2,3,4};
		/* set of period */
param personSkills{p in PERSON, s in SKILL}, >= 0;
		/* skills of agent PERSON */
param taskSkills{t in TASK, s in SKILL}, >= 0;
		/* skills of task TASK */
param personPeriods{p in PERSON, a in PERIOD}, >= 0;
		/* availability of agent PERSON */
param taskPeriods{t in TASK, a in PERIOD}, >= 0;
		/* availability of task TASK */

var x{p in PERSON, t in TASK, a in PERIOD}, >= 0;
		/* x[p,t,a] = 1 means task t is assigned to agent p at a given time a. Note that variables x[p,t,a] are binary, however, there is no need to declare them so due to the totally unimodular constraint matrix */

maximize obj: sum{p in PERSON, t in TASK, a in PERIOD} x[p,t,a];
		/* the objective is to find a max assignment */


		s.t. constraintPersons{p in PERSON}: sum{t in TASK, a in PERIOD} x[p,t,a] <= 1;
		/* each agent can perform at most one task at given time */

		s.t. constraintTasks{t in TASK}: sum{p in PERSON, a in PERIOD} x[p,t,a] <= 1;
		/* each task can be assigned to at most one agent  at given time */

		s.t. constraintSkills{p in PERSON, t in TASK, s in SKILL, a in PERIOD}: taskSkills[t,s] * x[p,t,a] <= personSkills[p,s];
		/* each task required skills must match to assigned agent skills */

		s.t. constraintPeriods{p in PERSON, t in TASK, a in PERIOD}: taskPeriods[t,a] * x[p,t,a] <= personPeriods[p,a];
		/* each task required period must match to assigned agent availability */


solve;

for {p in PERSON, t in TASK, a in PERIOD}  {printf "%d;%d;%d;%d;\n", p,t,a,x[p,t,a];}

data;

param personSkills : 
   1 2 3 4 5 6 :=
 1 1 0 0 1 0 0 
 2 0 1 0 1 0 1 
 3 0 0 0 0 1 0 
 4 0 0 0 0 0 0 
 5 0 0 1 0 0 1 
 6 0 0 0 1 0 1 
 7 1 0 0 0 0 0 
 8 0 1 1 0 0 0 
 9 1 1 0 0 1 1 
 10 0 1 1 0 0 0 
 11 0 0 0 1 0 0 ;


param taskSkills : 
   1 2 3 4 5 6 :=
 1 0 1 0 0 0 0 
 2 1 1 0 0 0 0 
 3 0 0 0 0 1 0 
 4 0 1 1 0 0 0 
 5 0 0 0 0 0 1 
 6 0 0 1 0 0 1 
 7 1 0 0 0 0 0 
 8 0 0 0 1 0 0 
 9 1 1 0 1 0 1 
 10 0 0 0 0 0 0 ;


param personPeriods : 
   1 2 3 4 :=
 1 1 1 1 1 
 2 0 0 0 1 
 3 1 1 1 1 
 4 1 1 1 1 
 5 1 1 1 1 
 6 1 1 1 1 
 7 1 1 1 1 
 8 0 0 0 0 
 9 0 0 1 0 
 10 1 1 1 1 
 11 1 1 1 1 ;


param taskPeriods : 
   1 2 3 4 :=
 1 1 1 0 0 
 2 0 0 1 0 
 3 1 1 1 0 
 4 1 1 0 0 
 5 0 1 1 1 
 6 1 1 1 1 
 7 0 0 1 1 
 8 0 0 0 1 
 9 0 1 1 1 
 10 1 1 1 1 ;

end;
